Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Mysteriozni Z. 09. 11. 2016, 20:18:43

Název: Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 20:18:43
Mám řekněme následující kód:

Kód: [Vybrat]
Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(File::isFile)
            .forEach(file -> System.out.println(file.getAbsolutePath()));

Konkrétně mi jde o tohle: .filter(File::isFile)


Funkce File::isFile vypadá následovně:

Kód: [Vybrat]
  public boolean isFile() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
    }

Pochopil bych, kdyby File::isFile byla staticka tridni metoda

Kód: [Vybrat]
public static boolean isFile(File file) { ... }

Potom by mi bylo jasne, jak .filter(File::isFile) funguje, tj. pres funkcni interface. Jenze funkce isFile() se musi zavolat nad instanci tridy File a ja nechapu, jak se toho da dosahnout pomoci lambd. Muzete mi to nekdo vysvetlit?

Dik
Název: Re:Monády v Javě
Přispěvatel: dustin 09. 11. 2016, 20:38:44
Objekt třídy File do toho filtru leze z mapovací (tedy konverzní) metody map toFile.
Název: Re:Monády v Javě
Přispěvatel: pecrom 09. 11. 2016, 21:12:22
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 21:57:43
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?
Název: Re:Monády v Javě
Přispěvatel: Ondra Satai Nekola 09. 11. 2016, 22:03:10
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?

Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 22:12:40
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?


Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.

Mohl by jsi prosim napsat uryvek, jak to priblizne v te motode filter() vypada? Ty vis, ze se ma zavolat metoda File::isFile. Mas taky instanci tridy File, nad kterou se ma isFile zavolat. Jak to teda udelas jinak nez pomoci reflexe:

Kód: [Vybrat]
method.invoke(obj, arg1, arg2,...);
Název: Re:Monády v Javě
Přispěvatel: Ondra Satai Nekola 09. 11. 2016, 22:22:17
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?


Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.

Mohl by jsi prosim napsat uryvek, jak to priblizne v te motode filter() vypada? Ty vis, ze se ma zavolat metoda File::isFile. Mas taky instanci tridy File, nad kterou se ma isFile zavolat. Jak to teda udelas jinak nez pomoci reflexe:

Kód: [Vybrat]
method.invoke(obj, arg1, arg2,...);

Java je OSS.
Název: Re:Monády v Javě
Přispěvatel: javaman (( 09. 11. 2016, 22:29:16
Tohle nedá ani většina Java lopat, takže začátečník nemá skoro šanci bez velkého studia :D
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Zeli 09. 11. 2016, 22:29:47
Tak bys mohl vedEt, ze si v te meTode filtr nic neprectu, protoze je to vsechno udelane pres interface.
Název: Re:Monády v Javě
Přispěvatel: dustin 09. 11. 2016, 22:33:18
Tohle nedá ani většina Java lopat, takže začátečník nemá skoro šanci bez velkého studia :D

Ale houby, není to žádná věda. Bereš prachy, tak se taky nauč něco nového užitečného. Nebo ti na všechno dává zaměstnavatel lidi a sám nemusíš umět nic, jenom žvanit a chvástat se?
Název: Re:Monády v Javě
Přispěvatel: Ondra Satai Nekola 09. 11. 2016, 22:36:26
Tak bys mohl vedEt, ze si v te meTode filtr nic neprectu, protoze je to vsechno udelane pres interface.

To je takovy problem se dobrat implementace? (on by ti mel stacit i ten interface, aby sis vsimnul tech generik).

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/stream/ReferencePipeline.java#l160 by ti mohlo pomoci. Ale zrovna tady ta konkretni implementace spis zamlzi, je tam dost detailu, od kterych te interface odstini.
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Zeli 09. 11. 2016, 22:44:52
To mi porad nepomohlo. Ano vsiml jsem si generik. Ale generIka ti nijak nepomuzou aby jsi zavolal obecne metodu x nad instanci tridy y.
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 22:49:27
Ok takze ptam se dal. Mam:

Kód: [Vybrat]
@Override
    public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
        Objects.requireNonNull(predicate);
        return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SIZED) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                    @Override
                    public void begin(long size) {
                        downstream.begin(-1);
                    }

                    @Override
                    public void accept(P_OUT u) {
                        if (predicate.test(u))
                            downstream.accept(u);
                    }
                };
            }
        };
    }

Porad tam nevidim odpoved na co se ptam, jsem u:

Kód: [Vybrat]
predicate.test(u);
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 22:57:24
Rozumim teto variante:

Kód: [Vybrat]
Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(file -> file.isFile())
            .forEach(file -> System.out.println(file.getAbsolutePath()));

Protoze jsem to JA, kdo tam napise, co se ma konkretne zavolat nad file. Ale ne teto variante, paklize tam vnitrne neni pouzita reflexe nebo File::isFile neni tridni metoda:

Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(File::isFile())
            .forEach(file -> System.out.println(file.getAbsolutePath()));
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 22:59:03
Kdo to vysvetli je borec.
Název: Re:Monády v Javě
Přispěvatel: Ondra Satai Nekola 09. 11. 2016, 23:03:53
Už tam skoro jsi:

https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 23:07:24
Ok, tak já to ukončím. Borec jsem tady já. File::isFile, resp. X::method, kompilátor nahradí lambdou: x  -> x.method

Gratuluji. Bylo to tak těžké říct? Asi jo, protože to tu ani Satai Nekola neví.
Název: Re:Monády v Javě
Přispěvatel: DK 09. 11. 2016, 23:08:20
Volas metodu isFile z tridy File, jelikoz je to metoda nestaticka, aplikuje se na objekt daneho streamu. Jelikoz je objekt typu File, tak to projde, jinak by kompilator zahlasil chybu.

Ber to tak, ze kompilator si to interne prepise na f -> f.isFile() (je to predikat, muze se zapsat nekolika zpusoby


// nez jsem to dopsal, pan Mysteriozni si odpovedel... nebylo, rikali ti to vsichni od zacatku
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 23:11:29
Volas metodu isFile z tridy File, jelikoz je to metoda nestaticka, aplikuje se na objekt daneho streamu. Jelikoz je objekt typu File, tak to projde, jinak by kompilator zahlasil chybu.

Ber to tak, ze kompilator si to interne prepise na f -> f.isFile() (je to predikat, muze se zapsat nekolika zpusoby


// nez jsem to dopsal, pan Mysteriozni si odpovedel... nebylo, rikali ti to vsichni od zacatku

Ukaž mi jediný příspěvek, ve kterém někdo napsal:

File::isFile ti kompilátor přepíše na file -> file.isFile()

a jsi možná jsi taky borec jako já.
Název: Re:Monády v Javě
Přispěvatel: Mysteriozni Z. 09. 11. 2016, 23:15:53
Jednoduchá odpověď, necelých 10 slov. Tak buďto to tady nikdo nevěděl a nebo podle DK mi to všichni říkali, což z nich ovšem dělá solidní autisty že to neumí sdělit jasně a stručně. Zase porod na půl hodiny se tu na root něco dozvědět.
Název: Re:Monády v Javě
Přispěvatel: Ondra Satai Nekola 09. 11. 2016, 23:20:49
Ok, tak já to ukončím. Borec jsem tady já. File::isFile, resp. X::method, kompilátor nahradí lambdou: x  -> x.method

Gratuluji. Bylo to tak těžké říct? Asi jo, protože to tu ani Satai Nekola neví.

Compiler nic neprepise,  tyhle vyrazy jsou ta sama lambda.
Název: Re:Monády v Javě
Přispěvatel: DK 10. 11. 2016, 07:10:22
Popsal to dustin hned ve druhem prispevku, nebo pecrom ve tretim.

presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.
Název: Re:Monády v Javě
Přispěvatel: lanka 10. 11. 2016, 08:55:26
Jednoduchá odpověď, necelých 10 slov. Tak buďto to tady nikdo nevěděl a nebo podle DK mi to všichni říkali, což z nich ovšem dělá solidní autisty že to neumí sdělit jasně a stručně. Zase porod na půl hodiny se tu na root něco dozvědět.

Kdybys nebyl liny a precetl si libovolny tutorial, vedel bys to sam a nemusel by ses doprosovat na rootu. Zes to nepochopil neznamena, ze ostatni to neumi vysvetlit, ale ze mas dlouhe vedeni.
Název: Re:Monády v Javě
Přispěvatel: podlesh 10. 11. 2016, 09:48:33
Pro ty kteří v tom pořád nemají jasno a nepřečetli si https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html):
Pokud se použije syntaxe SomeClass::nonStaticMethod, tak výsledná lambda má vždy o jeden parametr navíc - jako první je instance té třídy (tedy efektivně this). To znamená že File::isFile má ve výsledku jeden parametr, typu File.
Název: Re:Monády v Javě
Přispěvatel: Kolemjdoucí 10. 11. 2016, 09:54:25
Pro ty kteří v tom pořád nemají jasno a nepřečetli si https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html):
Pokud se použije syntaxe SomeClass::nonStaticMethod, tak výsledná lambda má vždy o jeden parametr navíc - jako první je instance té třídy (tedy efektivně this). To znamená že File::isFile má ve výsledku jeden parametr, typu File.

Nebo obecněji: vždy pokud se volá nestatická metoda tak ta metoda má o jeden parametr navíc (this).